<template>
  <div class="categories-view">
    <div class="page-header">
      <h1>商品分类管理</h1>
      <p>管理商品分类，支持多级分类结构</p>
    </div>

    <el-card class="content-card" shadow="hover">
      <template #header>
        <div class="card-header">
          <span>分类列表</span>
          <el-button type="primary" :icon="Plus" @click="handleAdd()">添加分类</el-button>
        </div>
      </template>

      <!-- 分类树形表格 -->
      <el-table
        ref="tableRef"
        v-loading="loading"
        :data="categoryTree"
        row-key="id"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        :default-expand-all="false"
        style="width: 100%"
        @row-click="handleRowClick"
      >
        <el-table-column prop="name" label="分类名称" min-width="200">
          <template #default="{ row }">
            <div class="category-name" :class="{ 'is-root': row.parent_id === 0, 'is-child': row.parent_id !== 0 }">
              <el-image
                v-if="row.icon_url"
                :src="row.icon_url"
                class="category-icon"
                fit="cover"
              />
              <span class="category-title">{{ row.name }}</span>
            </div>
          </template>
        </el-table-column>

        <el-table-column prop="sort_order" label="排序" width="100" align="center" />

        <el-table-column prop="created_at" label="创建时间" width="180" align="center">
          <template #default="{ row }">
            {{ formatDate(row.created_at) }}
          </template>
        </el-table-column>

        <el-table-column label="操作" width="280" align="center" property="actions">
          <template #default="{ row }">
            <div class="action-buttons">
              <el-button
                type="primary"
                size="small"
                :icon="Plus"
                @click="handleAdd(row)"
              >
                添加子分类
              </el-button>
              <el-button
                type="warning"
                size="small"
                :icon="Edit"
                @click="handleEdit(row)"
              >
                编辑
              </el-button>
              <el-button
                type="danger"
                size="small"
                :icon="Delete"
                @click="handleDelete(row)"
              >
                删除
              </el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 添加/编辑分类对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="500px"
      @close="resetForm"
    >
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="100px"
      >
        <el-form-item label="父分类" prop="parent_id">
          <el-tree-select
            v-model="form.parent_id"
            :data="categoryOptions"
            :props="{ value: 'id', label: 'name', children: 'children' }"
            placeholder="请选择父分类（不选则为顶级分类）"
            clearable
            check-strictly
            style="width: 100%"
          />
        </el-form-item>

        <el-form-item label="分类名称" prop="name">
          <el-input
            v-model="form.name"
            placeholder="请输入分类名称"
            maxlength="50"
            show-word-limit
          />
        </el-form-item>

        <el-form-item label="分类图标" prop="icon_url">
          <el-upload
            class="icon-uploader"
            :action="uploadUrl"
            :headers="uploadHeaders"
            :show-file-list="false"
            :on-success="handleIconSuccess"
            :before-upload="beforeIconUpload"
          >
            <img v-if="form.icon_url" :src="form.icon_url" class="icon-preview" />
            <el-icon v-else class="icon-uploader-icon"><Plus /></el-icon>
          </el-upload>
          <div class="upload-tip">建议上传 100x100 像素的图片</div>
        </el-form-item>

        <el-form-item label="排序值" prop="sort_order">
          <el-input-number
            v-model="form.sort_order"
            :min="0"
            :max="999"
            placeholder="数值越小排序越靠前"
            style="width: 100%"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" :loading="submitting" @click="handleSubmit">
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox, type FormInstance } from 'element-plus'
import { Plus, Edit, Delete } from '@element-plus/icons-vue'
import { useAuthStore } from '@/stores/auth'
import request from '@/utils/request'

// 状态管理
const authStore = useAuthStore()
const loading = ref(false)
const submitting = ref(false)
const dialogVisible = ref(false)
const categoryTree = ref([])
const formRef = ref<FormInstance>()
const tableRef = ref()
// 表单数据
const form = reactive({
  id: null,
  parent_id: null,
  name: '',
  icon_url: '',
  sort_order: 99
})

// 表单验证规则
const rules = {
  name: [
    { required: true, message: '请输入分类名称', trigger: 'blur' },
    { min: 1, max: 50, message: '分类名称长度在 1 到 50 个字符', trigger: 'blur' }
  ]
}

// 计算属性
const dialogTitle = computed(() => {
  return form.id ? '编辑分类' : '添加分类'
})

const categoryOptions = computed(() => {
  // 构建分类选择树，排除当前编辑的分类及其子分类
  const buildOptions = (categories: any[], excludeId?: number | null): any[] => {
    return categories
      .filter(cat => cat.id !== excludeId)
      .map(cat => ({
        id: cat.id,
        name: cat.name,
        children: cat.children ? buildOptions(cat.children, excludeId) : []
      }))
  }
  return buildOptions(categoryTree.value, form.id)
})

const uploadUrl = computed(() => {
  return `${import.meta.env.VITE_API_BASE_URL}/upload/image`
})

const uploadHeaders = computed(() => {
  return {
    'Authorization': `Bearer ${authStore.token}`
  }
})

// 方法
const formatDate = (dateString: string) => {
  return new Date(dateString).toLocaleString('zh-CN')
}

const loadCategories = async () => {
  try {
    loading.value = true
    const response = await request.get('/categories/tree')
    categoryTree.value = response.data
  } catch (error) {
    console.error('加载分类失败:', error)
    ElMessage.error('加载分类失败')
  } finally {
    loading.value = false
  }
}

// 处理行点击事件
const handleRowClick = (row: any, column: any, event: Event) => {
  // 如果点击的是操作列，不触发展开/收起
  if (column && column.property === 'actions') {
    return
  }

  // 如果有子分类，切换展开状态
  if (row.children && row.children.length > 0) {
    tableRef.value?.toggleRowExpansion(row)
  }
}

const handleAdd = (parent?: any) => {
  resetForm()
  if (parent) {
    form.parent_id = parent.id
  }
  dialogVisible.value = true
}

const handleEdit = (row: any) => {
  resetForm()
  form.id = row.id
  form.parent_id = row.parent_id || null
  form.name = row.name
  form.icon_url = row.icon_url || ''
  form.sort_order = row.sort_order
  dialogVisible.value = true
}

const handleDelete = async (row: any) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除分类"${row.name}"吗？删除后不可恢复！`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )

    await request.delete(`/categories/${row.id}`)
    ElMessage.success('删除成功')
    await loadCategories()
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('删除分类失败:', error)
      ElMessage.error(error.response?.data?.message || '删除失败')
    }
  }
}

const handleSubmit = async () => {
  if (!formRef.value) return

  try {
    await formRef.value.validate()
    submitting.value = true

    const data = {
      parent_id: form.parent_id || 0,
      name: form.name,
      icon_url: form.icon_url,
      sort_order: form.sort_order
    }

    if (form.id) {
      await request.put(`/categories/${form.id}`, data)
      ElMessage.success('更新成功')
    } else {
      await request.post('/categories', data)
      ElMessage.success('创建成功')
    }

    dialogVisible.value = false
    await loadCategories()
  } catch (error: any) {
    console.error('提交失败:', error)
    ElMessage.error(error.response?.data?.message || '操作失败')
  } finally {
    submitting.value = false
  }
}

const resetForm = () => {
  form.id = null
  form.parent_id = null
  form.name = ''
  form.icon_url = ''
  form.sort_order = 99

  if (formRef.value) {
    formRef.value.clearValidate()
  }
}

const handleIconSuccess = (response: any) => {
  if (response.success) {
    form.icon_url = response.data.url
    ElMessage.success('图片上传成功')
  } else {
    ElMessage.error(response.message || '上传失败')
  }
}

const beforeIconUpload = (file: File) => {
  const isImage = file.type.startsWith('image/')
  const isLt2M = file.size / 1024 / 1024 < 2

  if (!isImage) {
    ElMessage.error('只能上传图片文件!')
    return false
  }
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过 2MB!')
    return false
  }
  return true
}

// 生命周期
onMounted(() => {
  loadCategories()
})
</script>

<style scoped>
.categories-view {
  max-width: 1200px;
  margin: 0 auto;
}

.page-header {
  margin-bottom: 24px;
}

.page-header h1 {
  margin: 0 0 8px 0;
  font-size: 24px;
  font-weight: 600;
  color: #303133;
}

.page-header p {
  margin: 0;
  color: #606266;
  font-size: 14px;
}

.content-card {
  border-radius: 8px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;
}

.category-name {
  display: flex;
  align-items: center;
  gap: 8px;
}

.category-icon {
  width: 24px;
  height: 24px;
  border-radius: 4px;
  flex-shrink: 0;
}

.icon-uploader {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: border-color 0.3s;
}

.icon-uploader:hover {
  border-color: #409eff;
}

.icon-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 100px;
  height: 100px;
  text-align: center;
  line-height: 100px;
}

.icon-preview {
  width: 100px;
  height: 100px;
  display: block;
  object-fit: cover;
}

.upload-tip {
  margin-top: 8px;
  font-size: 12px;
  color: #999;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.action-buttons {
  display: flex;
  gap: 8px;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: center;
}

/* 树形表格箭头样式调整 */
:deep(.el-table .el-table__expand-icon) {
  float: right !important;
  margin-left: auto !important;
  margin-right: 8px !important;
  cursor: pointer !important;
}

:deep(.el-table .el-table__cell) {
  position: relative;
}

/* 确保分类名称容器不阻挡箭头 */
.category-name {
  pointer-events: none;
}

.category-name > * {
  pointer-events: auto;
}

.category-name {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-right: 30px; /* 为箭头留出空间 */
  position: relative;
  min-height: 32px;
}

/* 根分类样式 - 简洁醒目 */
.category-name.is-root .category-title {
  font-weight: 600;
  font-size: 14px;
  color: #303133;
}

/* 有子分类的根分类可以点击 */
:deep(.el-table__row) .category-name.is-root {
  cursor: pointer;
}

:deep(.el-table__row) .category-name.is-root:hover {
  background-color: #f5f7fa;
  border-radius: 4px;
}

/* 子分类样式 - 简单缩进 */
.category-name.is-child {
  padding-left: 24px; /* 简单缩进 */
}

.category-name.is-child .category-title {
  font-weight: 400;
  font-size: 13px;
  color: #606266;
}

/* 子分类前的简单连接线 */
.category-name.is-child::before {
  content: '';
  position: absolute;
  left: 12px;
  top: 50%;
  width: 8px;
  height: 1px;
  background-color: #dcdfe6;
}

.category-name.is-child::after {
  content: '';
  position: absolute;
  left: 12px;
  top: 0;
  bottom: 50%;
  width: 1px;
  background-color: #dcdfe6;
}

/* 图标样式 */
.category-icon {
  width: 20px;
  height: 20px;
  border-radius: 3px;
}

/* 简洁的hover效果 */
:deep(.el-table__row:hover) .category-title {
  color: #409eff;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .categories-view {
    margin: 0 16px;
  }

  .el-table-column {
    min-width: auto !important;
  }

  .category-name.is-child {
    padding-left: 20px; /* 移动端减少缩进 */
  }

  .action-buttons {
    flex-direction: column;
    gap: 4px;
  }

  .action-buttons .el-button {
    width: 100%;
    margin: 0;
  }
}
</style>
